<?php

namespace app\zyhsmarketing\lib;

use app\zyhsapi\model\marketing\ZyhsMarketingCallbackRecode;
use app\zyhsapi\model\marketing\ZyhsVivoMarketingData;
use app\zyhsapi\model\marketing\ZyhsVivoMarketingTokenInfo;
use GuzzleHttp\Exception\GuzzleException;
use think\Db;
use think\Log;
use XznsTools\curl\Curl;

class VivoMarketing
{
    private $clientId = '20240316002';
    private $clientSecret = '54095BEC46458348F677CD9C5D64E91B231ADBA7F44B00FE430764106ABB4C10';

    private $marketingCallbackUrl = 'https://marketing-api.vivo.com.cn/openapi/v1/advertiser/behavior/upload';

//    第一次获取token时浏览器打开此地址获取 authorizationCode  "https://open-ad.vivo.com.cn/OAuth?clientId=20240316002&state=54095BEC46458348F677CD9C5D64E91B231ADBA7F44B00FE430764106ABB4C10&redirectUri=https://beta-wechat.goddessxzns.com/zyhsmarketing/vivo/getCode";
    private $authorizationCode = 'c0c9d2a27876e80839069159e89cdc68fbbce228fffe43f4c40d3251173f3732';

    private $getToken = "https://marketing-api.vivo.com.cn/openapi/v1/oauth2/token";//第一次获取token
    private $refreshToken = "https://marketing-api.vivo.com.cn/openapi/v1/oauth2/refreshToken";//刷新token

    private $monitorClickUrl = "/zyhsmarketing/vivo/click?os=_OS_&imei=_IMEI_&ip=_IP_&oaid=_OAID_&oaidplain=_OAIDPLAIN_&ua=_UA_&androidid=_ANDROIDID_&location_LOCATION_&requestid=_REQUESTID_&requestname=_REUQESTNAME_&advertiserid=_ADVERTISERID_&adname=_ADNAME_&creativeid=_CREATIEID_&osversion=_OSVERSION_&model=_MODEL_&lang=_LANG_&resolution=_RESOLUTION_&nettype=_NETTYPE_&ts=_TS_&rtaexp=_RTAEXP_";//vivo营销平台点击检测链接地址

    /**
     * token 信息
     * @var string
     */
    private $token = '';

    public function getToken()
    {
        $nowTime = time();
        if ($this->token)
        {
            return $this->token;
        }
        $tokenInfo = (new ZyhsVivoMarketingTokenInfo())->where('client_id', $this->clientId)->field('extend')->find();
        if ($tokenInfo)
        {
            $tokenInfo = json_decode($tokenInfo['extend'], true);
            if ($tokenInfo['token_date'] > $nowTime * 1000 + 86400)
            {
                $resToken = $tokenInfo['access_token'];
            } else
            {
                $resTokenData = Curl::request($this->refreshToken, [
                    'client_id' => $this->clientId,
                    'client_secret' => $this->clientSecret,
                    'refresh_token' => $tokenInfo['refresh_token'],
                ], 'GET');
                if ($resTokenData['data']['code'] === 0)
                {

                    (new ZyhsVivoMarketingTokenInfo())->where('client_id', $this->clientId)->update(['extend' => json_encode($resTokenData['data']['data'], JSON_UNESCAPED_UNICODE)]);
                    $resToken = $resTokenData['data']['data']['access_token'];
                } else
                {
                    $resToken = '';
                    Log::write('获取token失败，VivoMarketing->getToken()：' . json_encode($resTokenData, JSON_UNESCAPED_UNICODE), 'error', true);
                }
            }

        } else
        {
            $resTokenData = Curl::request($this->getToken, [
                'grant_type' => 'code',
                'client_id' => $this->clientId,
                'client_secret' => $this->clientSecret,
                'code' => $this->authorizationCode,
            ], 'GET');
            if ($resTokenData['data']['code'] === 0)
            {

                (new ZyhsVivoMarketingTokenInfo())->insertGetId([
                    'client_id' => $this->clientId,
                    'extend' => json_encode($resTokenData['data']['data'], JSON_UNESCAPED_UNICODE),
                ]);
                $resToken = $resTokenData['data']['data']['access_token'];
            } else
            {
                $resToken = '';
                Log::write('获取token失败，VivoMarketing->getToken()：' . json_encode($resTokenData, JSON_UNESCAPED_UNICODE), 'error', true);
            }
        }
        return $resToken;
    }

    /**
     * 华为 Marketing API 回传转化数据
     * @param int $uid 用户uid
     * @param int $targetType 转化指标   1=>激活 2=>注册 3=>充值
     * @return void
     * @throws GuzzleException
     */
    public function callBack(string $oaid, int $uid, int $targetType)
    {
        try
        {
            switch ($targetType)
            {
                case 1:
                    $targetTypeDes = 'ACTIVATION';
                    break;
                case 2:
                    $targetTypeDes = 'REGISTER';
                    break;
                case 3:
                    $targetTypeDes = 'PAY';
                    break;
                default:
                    Log::write('未知的vivo回传转化类型', 'log', true);
                    return;
            }
            $nowTime = time();
            $nowTimestamp = $nowTime * 1000;
            $zyhsHuaweiMarketingDataModel = new ZyhsVivoMarketingData();
            $data = $zyhsHuaweiMarketingDataModel->where(['oaid' => $oaid])->column('request_id,advertiser_id', 'creative_id');
            if ($data)
            {   // 转化成功
                $token = $this->getToken();
                if (!$token)
                {
                    return;
                }
                $nonce = $this->createNonce($uid, 20);
                $zyhsMarketingCallbackRecodeModel = new ZyhsMarketingCallbackRecode();
                foreach ($data as $taskId => $item)
                {
                    $body = [
                        'srcType' => 'app',
                        'pkgName' => 'com.zhunle.rtc',//包名
                        'srcId' => 'ds-202403160824',//营销平台事件管理事件源id
                        'dataFrom' => 1,//0=测试事件，1=vivo事件
                        'dataList' => [
                            'userIdType' => 'oaid',
                            'userId' => $oaid,
                            'cvType' => $targetTypeDes,//事件类型
                            'cvTime' => $nowTimestamp,
//                                'cvParam' => 'param1:value1,param2:value2',
//                                'cvCustom' => '',
                            'requestId' => $item['request_id'],
                            'creativeId' => $taskId,
//                                'dlrSrc' => '',
//                                'installReferrer' => '',
//                                'extParam' => [
//                                    'payAmount' => '',
//                                    'unionId' => ''
//                                ]
                        ],
                    ];
                    $resData = Curl::request($this->marketingCallbackUrl . "?access_token={$token}&timestamp={$nowTimestamp}&nonce={$nonce}&advertiser_id={$item['advertiser_id']}",
                        $body, 'post',
                        [
                            'headers' => [
                                'Content-Type' => 'application/json',
                            ],
                        ], 'json');
                    if (!$resData['success'] || !isset($resData['data']['code']) || $resData['data']['code'] !== 0)
                    {
                        Db::table('good_wechat.zyhs_marketing_callback_error')->insert([
                            'mobile_type' => 3, // 华为=>5 小米=>4 vivo=>3 oppo=>2
                            'target_type' => $targetType,
                            'oaid' => $oaid,
                            'extend' => json_encode($resData, JSON_UNESCAPED_UNICODE),
                        ]);
                        Log::write('vivo回传失败，VivoMarketing->callBack()：' . json_encode($resData, JSON_UNESCAPED_UNICODE), 'error', true);
                    } else
                    {
                        // 添加 回传 记录
                        $zyhsMarketingCallbackRecodeModel->insert([
                            'task_id' => $taskId,
                            'uid' => $uid,
                            'type' => 3,
                            'oaid' => $oaid,
                            'target_type' => $targetType,
                            'create_time' => $nowTime,
                        ]);
                    }
                }
            }
        }
        catch (\Exception $e)
        {
            \think\Log::write(__CLASS__ . ' => ' . __FUNCTION__ . '()异常：' . $e->getMessage() . '失败信息：' . $e->getFile() . ':' . $e->getLine(), 'error', true);
        }
    }

    /**
     * 生成随机数
     * @param $uid
     * @param $length
     * @return string
     * @throws \Exception
     */
    public function createNonce($uid, $length)
    {
        $timestamp = round(microtime(true) * 1000);
        $random = random_int(10000000, 99999999);
        $uniqueString = $timestamp . $uid . $random;
        return substr(md5($uniqueString), 0, $length);
    }
}
